/**
 * @Copyright:Copyright (c) 2007 - 2023
 * 
 */
package com.tengtong.commons.lang;

import com.tengtong.commons.base.KeyValue;

/**
 * StringBuilder 的加强版本
 *
 * @author lin_jinming
 * @since: v1.0
 */
public class StringBuilderX {

    private final StringBuilder sb;
    
    public StringBuilderX() {
        this.sb = new StringBuilder();
    }
    
    public static StringBuilderX of(String...strings) {
        var result = new StringBuilderX();
        return result.appends(strings);
    }
    
    public StringBuilderX appends(String...strings) {
        if(strings != null) {
            ArrayUtils.eachArray(strings, this::append);
        }
        return this;
    }
    
    /**
     * 直接返回内部内容
     *
     * @return
     */
    public StringBuilder toStringBuilder() {
        return this.sb;
    }
    
    public int length(){
        return sb.length();
    }
    
    /**
     * 设置长度，如果 newLength = 0 表示清空内容
     *
     * @param newLength
     * @return
     */
    public StringBuilderX setLength(int newLength){
        sb.setLength(newLength);
        return this;
    }
    
    /**
     * 如果 s 为 null 或空，则添加 other，否则添加 s
     *
     * @param s
     * @param other
     * @return
     */
    public StringBuilderX appendOrElse(String s, String other) {
        if(StringUtils.notEmpty(s)) {
            sb.append(s);
        } else {
            sb.append(other);
        }
        return this;
    }
    
    /**
     * 如果 condition = true，则添加后面所有内容
     *
     * @param condition
     * @param s
     * @return
     */
    public StringBuilderX appends(boolean condition, String... s) {
        if(condition && ArrayUtils.notEmpty(s)) {
            ArrayUtils.eachArray(s, sb::append);
        }
        return this;
    }
    
    /**
     * 如果 o 为 null，就添加 other，否则添加 o
     *
     * @param o
     * @param other
     * @return
     */
    public StringBuilderX appendOrElse(Object o, Object other) {
        if(o == null) {
            sb.append(other);
        } else {
            sb.append(o);
        }
        return this;
    }
    
    public StringBuilderX appendIfPresent(Object o) {
        if(o != null) {
            sb.append(o);
        }
        return this;
    }
    
    /**
     * 使用 s 来替换原有内容
     *
     * @param s
     * @return
     */
    public StringBuilderX set(String s) {
        sb.setLength(0);
        sb.append(s);
        return this;
    }
    
    public StringBuilderX append(Object o) {
        this.sb.append(o);
        return this;
    }
    
    public StringBuilderX append(String s) {
        this.sb.append(s);
        return this;
    }
    
    public StringBuilderX append(int i) {
        this.sb.append(i);
        return this;
    }
    public StringBuilderX append(long l) {
        this.sb.append(l);
        return this;
    }
    public StringBuilderX append(short s) {
        this.sb.append(s);
        return this;
    }
    public StringBuilderX append(float s) {
        this.sb.append(s);
        return this;
    }
    public StringBuilderX append(double s) {
        this.sb.append(s);
        return this;
    }
    public StringBuilderX append(boolean s) {
        this.sb.append(s);
        return this;
    }
    public StringBuilderX append(CharSequence s) {
        this.sb.append(s);
        return this;
    }
    public StringBuilderX append(CharSequence s, int start, int end) {
        this.sb.append(s, start, end);
        return this;
    }
    
    public StringBuilderX append(char[] str) {
        this.sb.append(str);
        return this;
    }
    public StringBuilderX append(char[] str, int offset, int len) {
        this.sb.append(str, offset, len);
        return this;
    }
    public StringBuilderX append(StringBuffer s) {
        this.sb.append(s);
        return this;
    }
    
    public int compareTo(StringBuilder another) {
        return this.sb.compareTo(another);
    }
    
    public String toString() {
        return this.sb.toString();
    }
    
    public StringBuilderX append(boolean condition, int i) {
        if(condition) {
            sb.append(i);
        }
        return this;
    }
    
    public StringBuilderX append(boolean condition, Object o) {
        if(condition) {
            sb.append(o);
        }
        return this;
    }
    
    public StringBuilderX append(KeyValue nv) {
        if(nv != null) {
            sb.append(nv.toString());
        }
        return this;
    }
    
    /**
     * @since 1.5
     */

    public StringBuilderX appendCodePoint(int codePoint) {
        sb.appendCodePoint(codePoint);
        return this;
    }
    
    /**
     * 添加回车换行符
     *
     * @return
     */
    public StringBuilderX appendEnter() {
        return append("\n");
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX delete(int start, int end) {
        sb.delete(start, end);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX deleteCharAt(int index) {
        sb.deleteCharAt(index);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX replace(int start, int end, String str) {
        sb.replace(start, end, str);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int index, char[] str, int offset,
                                int len)
    {
        sb.insert(index, str, offset, len);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, Object obj) {
            sb.insert(offset, obj);
            return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, String str) {
        sb.insert(offset, str);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, char[] str) {
        sb.insert(offset, str);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int dstOffset, CharSequence s) {
            sb.insert(dstOffset, s);
            return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int dstOffset, CharSequence s,
                                int start, int end)
    {
        sb.insert(dstOffset, s, start, end);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, boolean b) {
        sb.insert(offset, b);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, char c) {
        sb.insert(offset, c);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, int i) {
        sb.insert(offset, i);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, long l) {
        sb.insert(offset, l);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, float f) {
        sb.insert(offset, f);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */

    public StringBuilderX insert(int offset, double d) {
        sb.insert(offset, d);
        return this;
    }

    public int indexOf(String str) {
        return sb.indexOf(str);
    }

    public int indexOf(String str, int fromIndex) {
        return sb.indexOf(str, fromIndex);
    }

    public int lastIndexOf(String str) {
        return sb.lastIndexOf(str);
    }

    public int lastIndexOf(String str, int fromIndex) {
        return sb.lastIndexOf(str, fromIndex);
    }

    public StringBuilderX reverse() {
        sb.reverse();
        return this;
    }
    
}
